use std::{thread, time::Duration};

use anyhow::{Ok, Result};
use concurrency::CmpMetrics;
use rand::Rng;

const N: usize = 4;
const M: usize = 10;
fn main() -> Result<()> {
    let metrics = CmpMetrics::new();
    for i in 0..N {
        task_worker(i, metrics.clone())?
    }
    for _idx in 0..M {
        request_worker(metrics.clone())?;
    }
    loop {
        thread::sleep(Duration::from_millis(5000));
        //let data = metrics.snapshot();
        println!("{}", metrics);
    }
    #[allow(unreachable_code)]
    Ok(())
}

fn task_worker(idx: usize, metrics: CmpMetrics) -> Result<()> {
    thread::spawn(move || {
        loop {
            let mut rng = rand::thread_rng();
            thread::sleep(Duration::from_millis(rng.gen_range(100..5000)));
            metrics.inc(format!("call.thread.worker.{}", idx))?;
        }

        #[allow(unreachable_code)]
        Ok(())
    });
    Ok(())
}
fn request_worker(metrics: CmpMetrics) -> Result<()> {
    thread::spawn(move || {
        loop {
            // process requests
            let mut rng = rand::thread_rng();
            thread::sleep(Duration::from_millis(rng.gen_range(100..5000)));
            let page = rng.gen_range(1..256);
            metrics.inc(format!("req.page.1{}", page))?;
        }
        #[allow(unreachable_code)]
        Ok(())
    });

    Ok(())
}
